package com.desaysv.svview.indicator;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.ScrollView;
import android.widget.TextView;


import com.desaysv.svview.R;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

public class IndicatorView extends LinearLayout {

    private static final String TAG = "IndicatorView";

    public IndicatorView(Context context) {
        this(context, null);
    }

    public IndicatorView(Context context, AttributeSet attrs) {
        this(context, attrs, -1);
    }

    public IndicatorView(Context context, AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr, -1);
    }

    public IndicatorView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context, attrs);
    }

    private View indicator;
    private ViewGroup rootContainer;
    private LinearLayout itemsContainer;
    private FrameLayout scrollView;

    private final static int SCROLL_AUTO = 0;
    private final static int SCROLL_FIXED = 1;
    private final static int FADE_OUT = 0;
    private final static int FADE_IN = 1;

    private boolean isHorizontal;
    private boolean needScroll;
    private final List<View> items = new ArrayList<>();
    private final List<View> indicatorItems = new ArrayList<>();

    private int indicatorWidth;
    private int indicatorHeight;

    private int animationDuring = 0;

    private int thisPaddingTop = 0;
    private int thisPaddingBottom = 0;
    private int thisPaddingLeft = 0;
    private int thisPaddingRight = 0;

    public interface OnItemSelectedListener {
        void onItemSelected(int position);
    }

    private OnItemSelectedListener listener;

    public void setOnItemSelectedListener(OnItemSelectedListener listener) {
        this.listener = listener;
    }

    private boolean isFadeOut = true;

    private int indicatorMarginTop;
    private int indicatorMarginLeft;
    private int indicatorMarginRight;
    private int indicatorMarginBottom;

    private int addTxtSize = -1;
    private int addItemBg = -1;
    private int addTxtColor = -1;

    @SuppressLint("RtlHardcoded")
    private void init(Context context, AttributeSet attrs) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.IndicatorView);
        //初始化指示器
        indicator = new View(context);
        //获取指示器的背景资源并设置
        int indicatorRes = typedArray.getResourceId(R.styleable.IndicatorView_indicator_bg, R.drawable.indicator_default);
        indicator.setBackgroundResource(indicatorRes);
        //获取item的方向
        int orientation = typedArray.getInt(R.styleable.IndicatorView_item_orientation, LinearLayout.HORIZONTAL);
        isHorizontal = orientation == LinearLayout.HORIZONTAL;

        int indicatorMode = typedArray.getInt(R.styleable.IndicatorView_indicator_mode, FADE_OUT);
        isFadeOut = indicatorMode == FADE_OUT;
        //整体滚动的根容器布局
        if (isFadeOut) {
            rootContainer = new LinearLayout(context);
        } else {
            rootContainer = new RelativeLayout(context);
        }
        //根据是否是水平排放还是垂直排放设置参数
        if (isHorizontal) {
            //水平排列item，如果指示器在out,那么跟容器就设置垂直排放，保证指示器和item容器不侵入
            if (isFadeOut) {
                assert rootContainer instanceof LinearLayout;
                ((LinearLayout) rootContainer).setOrientation(LinearLayout.VERTICAL);
            }
            rootContainer.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT));
            scrollView = new HorizontalScrollView(context);
            LayoutParams scrollViewLayoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
            scrollView.setLayoutParams(scrollViewLayoutParams);
        } else {
            //垂直排列item，如果指示器在out,那么跟容器就设置水平排放，保证指示器和item容器不侵入
            if (isFadeOut) {
                assert rootContainer instanceof LinearLayout;
                ((LinearLayout) rootContainer).setOrientation(LinearLayout.HORIZONTAL);
            }
            rootContainer.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
            scrollView = new ScrollView(context);
            LayoutParams scrollViewLayoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
            scrollView.setLayoutParams(scrollViewLayoutParams);
        }

        //初始化滚动容器
        scrollView.setHorizontalScrollBarEnabled(false);
        scrollView.setVerticalScrollBarEnabled(false);
        //获取指示器的宽高
        indicatorWidth = typedArray.getDimensionPixelSize(R.styleable.IndicatorView_indicator_width, isHorizontal ?  LayoutParams.MATCH_PARENT : 10);
        indicatorHeight = typedArray.getDimensionPixelSize(R.styleable.IndicatorView_indicator_height, isHorizontal ? 10 :  LayoutParams.MATCH_PARENT);
        //根据是否侵入式指示器配置设置对应的指示器LayoutParams 配置
        ViewGroup.LayoutParams layoutParams;
        if (isFadeOut) {
            layoutParams = new LayoutParams(indicatorWidth, indicatorHeight);
        } else {
            layoutParams = new RelativeLayout.LayoutParams(indicatorWidth, indicatorHeight);
        }
        int indicatorMargin = typedArray.getDimensionPixelSize(R.styleable.IndicatorView_indicator_margin, 0);
        indicatorMarginTop = typedArray.getDimensionPixelSize(R.styleable.IndicatorView_indicator_margin_top, 0);
        indicatorMarginLeft = typedArray.getDimensionPixelSize(R.styleable.IndicatorView_indicator_margin_left, 0);
        indicatorMarginRight = typedArray.getDimensionPixelSize(R.styleable.IndicatorView_indicator_margin_right, 0);
        indicatorMarginBottom = typedArray.getDimensionPixelSize(R.styleable.IndicatorView_indicator_margin_bottom, 0);

        animationDuring = typedArray.getInteger(R.styleable.IndicatorView_indicator_animation_during, 100);
        addTxtSize = typedArray.getDimensionPixelSize(R.styleable.IndicatorView_added_item_txt_size, -1);
        addItemBg = typedArray.getResourceId(R.styleable.IndicatorView_added_item_bg_selector, -1);
        addTxtColor = typedArray.getResourceId(R.styleable.IndicatorView_added_item_txt_selector, -1);

        int scroll_mode = typedArray.getInt(R.styleable.IndicatorView_scroll_mode, SCROLL_AUTO);
        needScroll = scroll_mode == SCROLL_FIXED;

        typedArray.recycle();
        if (indicatorMargin != 0) {
            indicatorMarginTop = indicatorMargin;
            indicatorMarginLeft = indicatorMargin;
            indicatorMarginRight = indicatorMargin;
            indicatorMarginBottom = indicatorMargin;
        }
        if (indicatorMarginTop != 0 && isFadeOut) {
            assert layoutParams instanceof LayoutParams;
            ((LayoutParams) layoutParams).topMargin = indicatorMarginTop;
        }
        if (indicatorMarginLeft != 0 && isFadeOut) {
            assert layoutParams instanceof LayoutParams;
            ((LayoutParams) layoutParams).leftMargin = indicatorMarginLeft;
        }
        if (indicatorMarginRight != 0 && isFadeOut) {
            assert layoutParams instanceof LayoutParams;
            ((LayoutParams) layoutParams).rightMargin = indicatorMarginRight;
        }
        if (indicatorMarginBottom != 0 && isFadeOut) {
            assert layoutParams instanceof LayoutParams;
            ((LayoutParams) layoutParams).bottomMargin = indicatorMarginBottom;
        }
        if (isHorizontal && !isFadeOut) {
            assert layoutParams instanceof RelativeLayout.LayoutParams;
            ((RelativeLayout.LayoutParams) layoutParams).addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
        }
        if (!isHorizontal && !isFadeOut) {
            assert layoutParams instanceof RelativeLayout.LayoutParams;
            ((RelativeLayout.LayoutParams) layoutParams).addRule(RelativeLayout.ALIGN_PARENT_START);
        }

        indicator.setLayoutParams(layoutParams);
        itemsContainer = new LinearLayout(context);
    }

    private final AtomicBoolean isFromProgram = new AtomicBoolean(false);
    private final List<View> programItem = new ArrayList<>();

    @SuppressLint("UseCompatLoadingForColorStateLists")
    public void addItem(String tabName) {
        post(() -> {
            TextView textView = new TextView(getContext());
            textView.setText(tabName);
            if (addTxtSize == -1) {
                if (isHorizontal) {
                    addTxtSize = this.getMeasuredHeight() / 2;
                } else {
                    addTxtSize = this.getMeasuredWidth() / 2;
                }
            }
            Log.e(TAG, "addItem: " + addTxtSize);
            textView.setTextSize(addTxtSize);
            LayoutParams layoutParams;
            if (isHorizontal) {
                layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
                textView.setPadding(10, 0, 10, 0);
                if (!needScroll) {
                    textView.setMinWidth(this.getMeasuredHeight());
                } else {
                    layoutParams.width = LayoutParams.MATCH_PARENT;
                }
            } else {
                layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
                textView.setPadding(0, 10, 0, 10);
                if (!needScroll) {
                    textView.setMinHeight(this.getMeasuredWidth());
                } else {
                    layoutParams.height = LayoutParams.MATCH_PARENT;
                }
            }
            if (!needScroll) {
                layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
                layoutParams.weight = 1;
            }
            textView.setGravity(Gravity.CENTER);
            textView.setLayoutParams(layoutParams);
            if (addTxtColor != -1) {
                textView.setTextColor(getResources().getColorStateList(addTxtColor,null));
            }
            addItem(textView);
        });
    }

    public void addItem(View view) {
        post(() -> {
            isFromProgram.set(true);
            LayoutParams layoutParams;
            if (isHorizontal) {
                layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
            } else {
                layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
            }
            if (!needScroll) {
                layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
                layoutParams.weight = 1;
            } else {
                if (isHorizontal) {
                    layoutParams.width = this.getMeasuredHeight();
                } else {
                    layoutParams.height = this.getMeasuredWidth();
                }
            }
            IndicatorItem indicatorItem = new IndicatorItem(getContext());
            indicatorItem.addView(view);
            indicatorItem.setLayoutParams(layoutParams);
            if (addItemBg != -1) {
                indicatorItem.setBackgroundResource(addItemBg);
            }
            indicatorItem.setOnClickListener(v -> {
                int position = indicatorItems.indexOf(v);
                selectItem(position, true);
            });
            programItem.add(indicatorItem);
            items.add(indicatorItem);
            indicatorItems.add(indicatorItem);

            resizeItems(false);
        });

    }

    public void removeItem(int position) {
        if (position < 0 || position >= items.size()) {
            throw new IllegalArgumentException("position must >=0 and <" + items.size());
        }
        if (isFromProgram.get()) {
            View removeItem = programItem.remove(position);
            items.remove(removeItem);
            indicatorItems.remove(removeItem);
            if (selectPosition > position) {
                selectPosition = indicatorItems.size() - 1;
            }
            resizeItems(false);
        } else {
            throw new RuntimeException("IndicatorView can only remove with program");
        }
    }

    private int thisWidth;
    private int thisHeight;

//    @Override
//    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
//        super.onLayout(changed, left, top, right, bottom);
//        Log.i(TAG, "onLayout: left=" + left + ",top=" + top + ",right=" + right + ",bottom=" + bottom + ",changed=" + changed);
//
//        if (!changed) {
//            return;
//        }
//        thisWidth = Math.abs(right - left);
//        thisHeight = Math.abs(bottom - top);
//        Log.i(TAG, "onLayout: thisWidth=" + thisWidth);
//        Log.i(TAG, "onLayout: thisHeight=" + thisHeight);
//        resizeItems(false);
//
//    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //测量控件的真实高度
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        if (width == 0 || height == 0) {
            return;
        }
        if (width == this.thisWidth && height == this.thisHeight) {
            return;
        }
        this.thisWidth = width;
        this.thisHeight = height;
        Log.i(TAG, "onMeasure: this.thisWidth="+this.thisWidth);
        Log.i(TAG, "onMeasure: this.thisHeight="+this.thisHeight);

        this.removeAllViews();
        resizeItems(true);
    }

    private int selectPosition = 0;

    public int getSelectPosition() {
        return selectPosition;
    }

    public void setSelectPosition(int selectPosition) {
        setSelectPosition(selectPosition, false);
    }

    public void setSelectPosition(int selectPosition, boolean withAnimation) {
        if (selectPosition < 0) {
            throw new IllegalArgumentException("selectPosition must >=0");
        }
        selectItem(selectPosition, withAnimation);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
//        //在布局加载完之后设置
//        this.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
//        thisWidth = getMeasuredWidth();
//        thisHeight = getMeasuredHeight();

        thisPaddingTop = this.getPaddingTop();
        thisPaddingLeft = this.getPaddingLeft();
        thisPaddingBottom = this.getPaddingBottom();
        thisPaddingRight = this.getPaddingRight();

//        Log.i(TAG, "onFinishInflate: thisWidth=" + thisWidth);
//        Log.i(TAG, "onFinishInflate: thisHeight=" + thisHeight);
        //先读取xml设置的item
        for (int i = 0; i < this.getChildCount(); i++) {
            items.add(getChildAt(i));
        }
        View lastView = null;
        boolean isSimpleItem = true;
        //判断xml设置的是不是简单布局
        for (View item : items) {
            if (lastView != null && !lastView.getClass().equals(item.getClass())) {
                isSimpleItem = false;
                break;
            }
            lastView = item;
        }
        //设置点击事件
        for (View item : items) {
            if (item instanceof IndicatorItem || isSimpleItem) {
                indicatorItems.add(item);
                item.setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        int position = indicatorItems.indexOf(v);
                        selectItem(position, true);
                    }
                });
            }
        }
//        resizeItems(true);
    }

    private void resizeItems(boolean isInflate) {
        if (this.indexOfChild(scrollView) == -1) {
            this.addView(scrollView);
        }
        if (scrollView.indexOfChild(rootContainer) == -1) {
            scrollView.addView(rootContainer);
        }
        Log.i(TAG, "resizeItems: thisWidth=" + thisWidth);
        Log.i(TAG, "resizeItems: thisHeight=" + thisHeight);
        ViewGroup.LayoutParams iLp=indicator.getLayoutParams();
        iLp.width = indicatorWidth== LayoutParams.MATCH_PARENT?thisWidth:indicatorWidth;
        iLp.height = indicatorHeight== LayoutParams.MATCH_PARENT?thisHeight:indicatorHeight;
        indicator.setLayoutParams(iLp);

        itemsContainer.removeAllViews();
        //根据容器排列方式设置item父容器的对应排列
        itemsContainer.setOrientation(isHorizontal ? LinearLayout.HORIZONTAL : LinearLayout.VERTICAL);
        ViewGroup.LayoutParams itemsContainerLp = null;
        if (isFadeOut) {
            //非侵入式就设置线性布局的权重
            itemsContainerLp = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
            ((LayoutParams) itemsContainerLp).weight = 1;
        } else {
            //侵入式就设置为相对布局
            itemsContainerLp = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        }
        //如果需要滚动，并且是水平排列，就设置item父容器宽度自适应
        if (needScroll && isHorizontal) {
            Log.i(TAG, "resizeContainer: 1 to " + thisWidth);
            itemsContainerLp.width = ViewGroup.LayoutParams.WRAP_CONTENT;
            itemsContainerLp.height = ViewGroup.LayoutParams.MATCH_PARENT;
        }
        //如果需要滚动，并且是垂直排列，就设置item父容器高度自适应
        if (needScroll && !isHorizontal) {
            Log.i(TAG, "resizeContainer: 2 to " + thisWidth);
            itemsContainerLp.width = ViewGroup.LayoutParams.MATCH_PARENT;
            itemsContainerLp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
        }
        //如果不需要滚动，并且是水平排列就设置item父容器宽度为整体控件的宽度
        if (!needScroll && isHorizontal) {
            Log.i(TAG, "resizeContainer: 3 to " + thisWidth);
            itemsContainerLp.width = thisWidth - thisPaddingLeft - thisPaddingRight;
            itemsContainerLp.height = ViewGroup.LayoutParams.MATCH_PARENT;
        }
        //如果不需要滚动，并且是垂直排列就设置item父容器高度为整体控件的高度
        if (!needScroll && !isHorizontal) {
            Log.i(TAG, "resizeContainer: 4 to " + thisHeight);
            itemsContainerLp.width = ViewGroup.LayoutParams.MATCH_PARENT;
            itemsContainerLp.height = thisHeight - thisPaddingTop - thisPaddingBottom;
        }
        itemsContainer.setLayoutParams(itemsContainerLp);
        Log.i(TAG, "resizeContainer: iLp.height="+iLp.height);
        Log.i(TAG, "resizeContainer: iLp.width()="+iLp.width);
        Log.i(TAG, "resizeContainer: isFadeOut="+isFadeOut);
        Log.i(TAG, "resizeContainer: isHorizontal="+isHorizontal);
        View lastView = null;
        boolean isSimpleItem = true;
        boolean indicatorNeedFirst = false;

        //如果是侵入式并且水平排列，并且指示器高度大于整体控件的高度的三分之一，就标记指示器需要显示在最低的层级
        if (!isFadeOut && isHorizontal && iLp.height >= thisHeight / 3) {
            indicatorNeedFirst = true;
        }
        //如果是侵入式并且垂直排列，并且指示器宽度大于整体控件的宽度的三分之一，就标记指示器需要显示在最低的层级
        if (!isFadeOut && !isHorizontal && iLp.width >= this.thisWidth / 3) {
            indicatorNeedFirst = true;
        }
        Log.i(TAG, "resizeItems: indicatorNeedFirst=" + indicatorNeedFirst);
        //标记是不是简单布局item
        for (View item : items) {
            if (lastView != null && !lastView.getClass().equals(item.getClass())) {
                isSimpleItem = false;
                break;
            }
            lastView = item;
        }

        if (!isFadeOut) {
            if (!indicatorNeedFirst) {
                if (rootContainer.indexOfChild(itemsContainer) == -1) {
                    rootContainer.addView(itemsContainer);
                }
                rootContainer.bringChildToFront(itemsContainer);
                if (rootContainer.indexOfChild(indicator) == -1) {
                    rootContainer.addView(indicator);
                }
                rootContainer.bringChildToFront(indicator); // 先提到最前
            } else {
                Log.e(TAG, "resizeItems: add indicator first");
                if (rootContainer.indexOfChild(indicator) == -1) {
                    rootContainer.addView(indicator);
                }
                rootContainer.bringChildToFront(indicator); // 先提到最前
                if (rootContainer.indexOfChild(itemsContainer) == -1) {
                    rootContainer.addView(itemsContainer);
                }
                rootContainer.bringChildToFront(itemsContainer);
            }
        } else {
            if (isHorizontal) {
                if (rootContainer.indexOfChild(itemsContainer) == -1) {
                    rootContainer.addView(itemsContainer);
                }
                if (rootContainer.indexOfChild(indicator) == -1) {
                    rootContainer.addView(indicator);
                }
            } else {
                if (rootContainer.indexOfChild(indicator) == -1) {
                    rootContainer.addView(indicator);
                }
                if (rootContainer.indexOfChild(itemsContainer) == -1) {
                    rootContainer.addView(itemsContainer);
                }
            }
        }
        for (View item : items) {
            if (item instanceof IndicatorItem || isSimpleItem) {
                //如果是侵入式底层布局方式，就让item的背景为透明，因为需要用指示器做背景
                if (indicatorNeedFirst) {
                    item.setBackgroundColor(Color.TRANSPARENT);
                }
                ViewGroup.LayoutParams oldItemLp = item.getLayoutParams();
                LayoutParams itemLp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
                //如果需要滚动就用设置的自身宽度或者高度
                if (needScroll && isHorizontal) {
                    Log.i(TAG, "resizeItems: 1");
                    itemLp.height = LayoutParams.MATCH_PARENT;
                    itemLp.width = oldItemLp.width;
                    itemLp.weight = 0;
                }
                if (needScroll && !isHorizontal) {
                    Log.i(TAG, "resizeItems: 2");
                    itemLp.width = LayoutParams.MATCH_PARENT;
                    itemLp.height = oldItemLp.height;
                    itemLp.weight = 0;
                }
                //如果不需要滚动就用权重平分
                if (!needScroll && isHorizontal) {
                    Log.i(TAG, "resizeItems: 3");
                    itemLp.width = 0;
                    itemLp.height = LayoutParams.MATCH_PARENT;
                    itemLp.weight = 1;
                }
                if (!needScroll && !isHorizontal) {
                    Log.i(TAG, "resizeItems: 4");
                    itemLp.width = LayoutParams.MATCH_PARENT;
                    itemLp.height = 0;
                    itemLp.weight = 1;
                }
                item.setLayoutParams(itemLp);
            }
            itemsContainer.addView(item);
        }
        if (isInflate) {
            selectItem(selectPosition, false);
        } else {
            post(() -> selectItem(selectPosition, false));
        }
    }

    private void selectItem(int position, boolean withAnimation) {
        if (position < 0 || indicatorItems.isEmpty()) {
            return;
        }
        View selectItem = indicatorItems.get(position);
        changeSelectedItem(position);
        ViewGroup.LayoutParams indicatorLp = indicator.getLayoutParams();
        Log.i(TAG, "selectItem: indicatorWidth=" + indicatorWidth + ",indicatorHeight=" + indicatorHeight + ",itemsContainer=" + itemsContainer.getMeasuredWidth());
        //如果是水平排列，并且是MATCH_PARENT，就根据item的宽度设置指示器的宽度
        if (indicatorWidth == LayoutParams.MATCH_PARENT && isHorizontal) {
            Log.i(TAG, "selectItem: selectItem.getMeasuredWidth()=" + selectItem.getMeasuredWidth());
            indicatorLp.width = selectItem.getMeasuredWidth() - indicatorMarginLeft - indicatorMarginRight;
        }
        //如果是垂直排列，并且是MATCH_PARENT，就根据item的高度设置指示器的高度
        if (indicatorHeight == LayoutParams.MATCH_PARENT && !isHorizontal) {
            Log.i(TAG, "selectItem: selectItem.getMeasuredHeight()=" + selectItem.getMeasuredHeight());
            indicatorLp.height = selectItem.getMeasuredHeight() - indicatorMarginTop - indicatorMarginBottom;
        }
        indicator.setLayoutParams(indicatorLp);
        if (isHorizontal) {
            int targetX = (selectItem.getMeasuredWidth() / 2 - (indicatorLp.width + indicatorMarginLeft + indicatorMarginRight) / 2) + selectItem.getLeft() + indicatorMarginLeft;
            if (!withAnimation) {
                indicator.animate().x(targetX).setDuration(0).start();
            } else {
                indicator.animate().x(targetX).setDuration(animationDuring).start();
            }
        } else {
            int targetY = (selectItem.getMeasuredHeight() / 2 - (indicatorLp.height + indicatorMarginTop + indicatorMarginBottom) / 2) + selectItem.getTop() + indicatorMarginTop;
            if (!withAnimation) {
                indicator.animate().y(targetY).setDuration(0).start();
            } else {
                indicator.animate().y(targetY).setDuration(animationDuring).start();
            }
        }
        if (selectPosition == position) {
            return;
        }
        selectPosition = position;
        if (listener != null) {
            listener.onItemSelected(selectPosition);
        }
    }

    private void changeSelectedItem(int position) {
        if (position < 0 || indicatorItems.isEmpty()) {
            return;
        }
        View selectItem = indicatorItems.get(position);
        for (View indicatorItem : indicatorItems) {
            if (selectItem.equals(indicatorItem)) {
                selectItem.setSelected(true);
            } else {
                indicatorItem.setSelected(false);
            }
        }
    }
}
